home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / vbcc-src / vcpp / eval.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  10KB  |  521 lines

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include "cpp.h"
  4.  
  5. #define    NSTAK    32
  6. #define    SGN    0
  7. #define    UNS    1
  8. #define    UND    2
  9.  
  10. #define    UNSMARK    0x1000
  11.  
  12. struct value {
  13.     long    val;
  14.     int    type;
  15. };
  16.  
  17. /* conversion types */
  18. #define    RELAT    1
  19. #define    ARITH    2
  20. #define    LOGIC    3
  21. #define    SPCL    4
  22. #define    SHIFT    5
  23. #define    UNARY    6
  24.  
  25. /* operator priority, arity, and conversion type, indexed by tokentype */
  26. struct pri {
  27.     char    pri;
  28.     char    arity;
  29.     char    ctype;
  30. } priority[] = {
  31.     { 0, 0, 0 },        /* END */
  32.     { 0, 0, 0 },        /* UNCLASS */
  33.     { 0, 0, 0 },        /* NAME */
  34.     { 0, 0, 0 },        /* NUMBER */
  35.     { 0, 0, 0 },        /* STRING */
  36.     { 0, 0, 0 },        /* CCON */
  37.     { 0, 0, 0 },        /* NL */
  38.     { 0, 0, 0 },        /* WS */
  39.     { 0, 0, 0 },        /* DSHARP */
  40.     { 11, 2, RELAT },    /* EQ */
  41.     { 11, 2, RELAT },    /* NEQ */
  42.     { 12, 2, RELAT },    /* LEQ */
  43.     { 12, 2, RELAT },    /* GEQ */
  44.     { 13, 2, SHIFT },    /* LSH */
  45.     { 13, 2, SHIFT },    /* RSH */
  46.     { 7, 2, LOGIC },    /* LAND */
  47.     { 6, 2, LOGIC },    /* LOR */
  48.     { 0, 0, 0 },        /* PPLUS */
  49.     { 0, 0, 0 },        /* MMINUS */
  50.     { 0, 0, 0 },        /* ARROW */
  51.     { 0, 0, 0 },        /* SBRA */
  52.     { 0, 0, 0 },        /* SKET */
  53.     { 3, 0, 0 },        /* LP */
  54.     { 3, 0, 0 },        /* RP */
  55.     { 0, 0, 0 },        /* DOT */
  56.     { 10, 2, ARITH },    /* AND */
  57.     { 15, 2, ARITH },    /* STAR */
  58.     { 14, 2, ARITH },    /* PLUS */
  59.     { 14, 2, ARITH },    /* MINUS */
  60.     { 16, 1, UNARY },    /* TILDE */
  61.     { 16, 1, UNARY },    /* NOT */
  62.     { 15, 2, ARITH },    /* SLASH */
  63.     { 15, 2, ARITH },    /* PCT */
  64.     { 12, 2, RELAT },    /* LT */
  65.     { 12, 2, RELAT },    /* GT */
  66.     { 9, 2, ARITH },    /* CIRC */
  67.     { 8, 2, ARITH },    /* OR */
  68.     { 5, 2, SPCL },        /* QUEST */
  69.     { 5, 2, SPCL },        /* COLON */
  70.     { 0, 0, 0 },        /* ASGN */
  71.     { 4, 2, 0 },        /* COMMA */
  72.     { 0, 0, 0 },        /* SHARP */
  73.     { 0, 0, 0 },        /* SEMIC */
  74.     { 0, 0, 0 },        /* CBRA */
  75.     { 0, 0, 0 },        /* CKET */
  76.     { 0, 0, 0 },        /* ASPLUS */
  77.      { 0, 0, 0 },        /* ASMINUS */
  78.      { 0, 0, 0 },        /* ASSTAR */
  79.      { 0, 0, 0 },        /* ASSLASH */
  80.      { 0, 0, 0 },        /* ASPCT */
  81.      { 0, 0, 0 },        /* ASCIRC */
  82.      { 0, 0, 0 },        /* ASLSH */
  83.     { 0, 0, 0 },        /* ASRSH */
  84.      { 0, 0, 0 },        /* ASOR */
  85.      { 0, 0, 0 },        /* ASAND */
  86.     { 0, 0, 0 },        /* ELLIPS */
  87.     { 0, 0, 0 },        /* DSHARP1 */
  88.     { 0, 0, 0 },        /* NAME1 */
  89.     { 16, 1, UNARY },    /* DEFINED */
  90.     { 16, 0, UNARY },    /* UMINUS */
  91. };
  92.  
  93. int    evalop(struct pri);
  94. struct    value tokval(Token *);
  95. struct value vals[NSTAK], *vp;
  96. enum toktype ops[NSTAK], *op;
  97.  
  98. /*
  99.  * Evaluate an #if #elif #ifdef #ifndef line.  trp->tp points to the keyword.
  100.  */
  101. long
  102. eval(Tokenrow *trp, int kw)
  103. {
  104.     Token *tp;
  105.     Nlist *np;
  106.     int ntok, rand;
  107.  
  108.     trp->tp++;
  109.     if (kw==KIFDEF || kw==KIFNDEF) {
  110.         if (trp->lp - trp->bp != 4 || trp->tp->type!=NAME) {
  111.             error(ERROR, "Syntax error in #ifdef/#ifndef");
  112.             return 0;
  113.         }
  114.         np = lookup(trp->tp, 0);
  115.         return (kw==KIFDEF) == (np && np->flag&(ISDEFINED|ISMAC));
  116.     }
  117.     ntok = trp->tp - trp->bp;
  118.     kwdefined->val = KDEFINED;    /* activate special meaning of defined */
  119.     expandrow(trp, "<if>");
  120.     kwdefined->val = NAME;
  121.     vp = vals;
  122.     op = ops;
  123.     *op++ = END;
  124.     for (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) {
  125.         switch(tp->type) {
  126.         case WS:
  127.         case NL:
  128.             continue;
  129.  
  130.         /* nilary */
  131.         case NAME:
  132.         case NAME1:
  133.         case NUMBER:
  134.         case CCON:
  135.         case STRING:
  136.             if (rand)
  137.                 goto syntax;
  138.             *vp++ = tokval(tp);
  139.             rand = 1;
  140.             continue;
  141.  
  142.         /* unary */
  143.         case DEFINED:
  144.         case TILDE:
  145.         case NOT:
  146.             if (rand)
  147.                 goto syntax;
  148.             *op++ = tp->type;
  149.             continue;
  150.  
  151.         /* unary-binary */
  152.         case PLUS: case MINUS: case STAR: case AND:
  153.             if (rand==0) {
  154.                 if (tp->type==MINUS)
  155.                     *op++ = UMINUS;
  156.                 if (tp->type==STAR || tp->type==AND) {
  157.                     error(ERROR, "Illegal operator * or & in #if/#elsif");
  158.                     return 0;
  159.                 }
  160.                 continue;
  161.             }
  162.             /* flow through */
  163.  
  164.         /* plain binary */
  165.         case EQ: case NEQ: case LEQ: case GEQ: case LSH: case RSH:
  166.         case LAND: case LOR: case SLASH: case PCT:
  167.         case LT: case GT: case CIRC: case OR: case QUEST:
  168.         case COLON: case COMMA:
  169.             if (rand==0)
  170.                 goto syntax;
  171.             if (evalop(priority[tp->type])!=0)
  172.                 return 0;
  173.             *op++ = tp->type;
  174.             rand = 0;
  175.             continue;
  176.  
  177.         case LP:
  178.             if (rand)
  179.                 goto syntax;
  180.             *op++ = LP;
  181.             continue;
  182.  
  183.         case RP:
  184.             if (!rand)
  185.                 goto syntax;
  186.             if (evalop(priority[RP])!=0)
  187.                 return 0;
  188.             if (op<=ops || op[-1]!=LP) {
  189.                 goto syntax;
  190.             }
  191.             op--;
  192.             continue;
  193.  
  194.         default:
  195.             error(ERROR,"Bad operator (%t) in #if/#elsif", tp);
  196.             return 0;
  197.         }
  198.     }
  199.     if (rand==0)
  200.         goto syntax;
  201.     if (evalop(priority[END])!=0)
  202.         return 0;
  203.     if (op!=&ops[1] || vp!=&vals[1]) {
  204.         error(ERROR, "Botch in #if/#elsif");
  205.         return 0;
  206.     }
  207.     if (vals[0].type==UND)
  208.         error(ERROR, "Undefined expression value");
  209.     return vals[0].val;
  210. syntax:
  211.     error(ERROR, "Syntax error in #if/#elsif");
  212.     return 0;
  213. }
  214.  
  215. int
  216. evalop(struct pri pri)
  217. {
  218.     struct value v1, v2;
  219.     long rv1, rv2;
  220.     int rtype, oper;
  221.  
  222.     rv2=0;
  223.     rtype=0;
  224.     while (pri.pri < priority[op[-1]].pri) {
  225.         oper = *--op;
  226.         if (priority[oper].arity==2) {
  227.             v2 = *--vp;
  228.             rv2 = v2.val;
  229.         }
  230.         v1 = *--vp;
  231.         rv1 = v1.val;
  232. /*lint -e574 -e644 */
  233.         switch (priority[oper].ctype) {
  234.         case 0:
  235.         default:
  236.             error(WARNING, "Syntax error in #if/#endif");
  237.             return 1;
  238.         case ARITH:
  239.         case RELAT:
  240.             if (v1.type==UNS || v2.type==UNS)
  241.                 rtype = UNS;
  242.             else
  243.                 rtype = SGN;
  244.             if (v1.type==UND || v2.type==UND)
  245.                 rtype = UND;
  246.             if (priority[oper].ctype==RELAT && rtype==UNS) {
  247.                 oper |= UNSMARK;
  248.                 rtype = SGN;
  249.             }
  250.             break;
  251.         case SHIFT:
  252.             if (v1.type==UND || v2.type==UND)
  253.                 rtype = UND;
  254.             else
  255.                 rtype = v1.type;
  256.             if (rtype==UNS)
  257.                 oper |= UNSMARK;
  258.             break;
  259.         case UNARY:
  260.             rtype = v1.type;
  261.             break;
  262.         case LOGIC:
  263.         case SPCL:
  264.             break;
  265.         }
  266.         switch (oper) {
  267.         case EQ: case EQ|UNSMARK:
  268.             rv1 = rv1==rv2; break;
  269.         case NEQ: case NEQ|UNSMARK:
  270.             rv1 = rv1!=rv2; break;
  271.         case LEQ:
  272.             rv1 = rv1<=rv2; break;
  273.         case GEQ:
  274.             rv1 = rv1>=rv2; break;
  275.         case LT:
  276.             rv1 = rv1<rv2; break;
  277.         case GT:
  278.             rv1 = rv1>rv2; break;
  279.         case LEQ|UNSMARK:
  280.             rv1 = (unsigned long)rv1<=rv2; break;
  281.         case GEQ|UNSMARK:
  282.             rv1 = (unsigned long)rv1>=rv2; break;
  283.         case LT|UNSMARK:
  284.             rv1 = (unsigned long)rv1<rv2; break;
  285.         case GT|UNSMARK:
  286.             rv1 = (unsigned long)rv1>rv2; break;
  287.         case LSH:
  288.             rv1 <<= rv2; break;
  289.         case LSH|UNSMARK:
  290.             rv1 = (unsigned long)rv1<<rv2; break;
  291.         case RSH:
  292.             rv1 >>= rv2; break;
  293.         case RSH|UNSMARK:
  294.             rv1 = (unsigned long)rv1>>rv2; break;
  295.         case LAND:
  296.             rtype = UND;
  297.             if (v1.type==UND)
  298.                 break;
  299.             if (rv1!=0) {
  300.                 if (v2.type==UND)
  301.                     break;
  302.                 rv1 = rv2!=0;
  303.             } else
  304.                 rv1 = 0;
  305.             rtype = SGN;
  306.             break;
  307.         case LOR:
  308.             rtype = UND;
  309.             if (v1.type==UND)
  310.                 break;
  311.             if (rv1==0) {
  312.                 if (v2.type==UND)
  313.                     break;
  314.                 rv1 = rv2!=0;
  315.             } else
  316.                 rv1 = 1;
  317.             rtype = SGN;
  318.             break;
  319.         case AND:
  320.             rv1 &= rv2; break;
  321.         case STAR:
  322.             rv1 *= rv2; break;
  323.         case PLUS:
  324.             rv1 += rv2; break;
  325.         case MINUS:
  326.             rv1 -= rv2; break;
  327.         case UMINUS:
  328.             if (v1.type==UND)
  329.                 rtype = UND;
  330.             rv1 = -rv1; break;
  331.         case OR:
  332.             rv1 |= rv2; break;
  333.         case CIRC:
  334.             rv1 ^= rv2; break;
  335.         case TILDE:
  336.             rv1 = ~rv1; break;
  337.         case NOT:
  338.             rv1 = !rv1; if (rtype!=UND) rtype = SGN; break;
  339.         case SLASH:
  340.             if (rv2==0) {
  341.                 rtype = UND;
  342.                 break;
  343.             }
  344.             if (rtype==UNS)
  345.                 rv1 /= (unsigned long)rv2;
  346.             else
  347.                 rv1 /= rv2;
  348.             break;
  349.         case PCT:
  350.             if (rv2==0) {
  351.                 rtype = UND;
  352.                 break;
  353.             }
  354.             if (rtype==UNS)
  355.                 rv1 %= (unsigned long)rv2;
  356.             else
  357.                 rv1 %= rv2;
  358.             break;
  359.         case COLON:
  360.             if (op[-1] != QUEST)
  361.                 error(ERROR, "Bad ?: in #if/endif");
  362.             else {
  363.                 op--;
  364.                 if ((--vp)->val==0)
  365.                     v1 = v2;
  366.                 rtype = v1.type;
  367.                 rv1 = v1.val;
  368.             }
  369.             break;
  370.         case DEFINED:
  371.             break;
  372.         default:
  373.             error(ERROR, "Eval botch (unknown operator)");
  374.             return 1;
  375.         }
  376. /*lint +e574 +e644 */
  377.         v1.val = rv1;
  378.         v1.type = rtype;
  379.         *vp++ = v1;
  380.     }
  381.     return 0;
  382. }
  383.  
  384. struct value
  385. tokval(Token *tp)
  386. {
  387.     struct value v;
  388.     Nlist *np;
  389.     int i, base, c;
  390.     unsigned long n;
  391.     uchar *p;
  392.  
  393.     v.type = SGN;
  394.     v.val = 0;
  395.     switch (tp->type) {
  396.  
  397.     case NAME:
  398.         v.val = 0;
  399.         break;
  400.  
  401.     case NAME1:
  402.         if ((np = lookup(tp, 0)) != NULL && np->flag&(ISDEFINED|ISMAC))
  403.             v.val = 1;
  404.         break;
  405.  
  406.     case NUMBER:
  407.         n = 0;
  408.         base = 10;
  409.         p = tp->t;
  410.         c = p[tp->len];
  411.         p[tp->len] = '\0';
  412.         if (*p=='0') {
  413.             base = 8;
  414.             if (p[1]=='x' || p[1]=='X') {
  415.                 base = 16;
  416.                 p++;
  417.             }
  418.             p++;
  419.         }
  420.         for (;; p++) {
  421.             if ((i = digit(*p)) < 0)
  422.                 break;
  423.             if (i>=base)
  424.                 error(WARNING,
  425.                   "Bad digit in number %t", tp);
  426.             n *= base;
  427.             n += i;
  428.         }
  429.         if (n>=0x80000000 && base!=10)
  430.             v.type = UNS;
  431.         for (; *p; p++) {
  432.             if (*p=='u' || *p=='U')
  433.                 v.type = UNS;
  434.             else if (*p=='l' || *p=='L')
  435.                 ;
  436.             else {
  437.                 error(ERROR,
  438.                   "Bad number %t in #if/#elsif", tp);
  439.                 break;
  440.             }
  441.         }
  442.         v.val = n;
  443.         tp->t[tp->len] = c;
  444.         break;
  445.  
  446.     case CCON:
  447.         n = 0;
  448.         p = tp->t;
  449.         if (*p=='L') {
  450.             p += 1;
  451.             error(WARNING, "Wide char constant value undefined");
  452.         }
  453.         p += 1;
  454.         if (*p=='\\') {
  455.             p += 1;
  456.             if ((i = digit(*p))>=0 && i<=7) {
  457.                 n = i;
  458.                 p += 1;
  459.                 if ((i = digit(*p))>=0 && i<=7) {
  460.                     p += 1;
  461.                     n <<= 3;
  462.                     n += i;
  463.                     if ((i = digit(*p))>=0 && i<=7) {
  464.                         p += 1;
  465.                         n <<= 3;
  466.                         n += i;
  467.                     }
  468.                 }
  469.             } else if (*p=='x') {
  470.                 p += 1;
  471.                 while ((i = digit(*p))>=0 && i<=15) {
  472.                     p += 1;
  473.                     n <<= 4;
  474.                     n += i;
  475.                 }
  476.             } else {
  477.                 static char cvcon[]
  478.                   = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\";
  479.                 for (i=0; i<sizeof(cvcon); i+=2) {
  480.                     if (*p == cvcon[i]) {
  481.                         n = cvcon[i+1];
  482.                         break;
  483.                     }
  484.                 }
  485.                 p += 1;
  486.                 if (i>=sizeof(cvcon))
  487.                     error(WARNING,
  488.                      "Undefined escape in character constant");
  489.             }
  490.         } else if (*p=='\'')
  491.             error(ERROR, "Empty character constant");
  492.         else
  493.             n = *p++;
  494.         if (*p!='\'')
  495.             error(WARNING, "Multibyte character constant undefined");
  496.         else if (n>127)
  497.             error(WARNING, "Character constant taken as not signed");
  498.         v.val = n;
  499.         break;
  500.  
  501.     case STRING:
  502.         error(ERROR, "String in #if/#elsif");
  503.         break;
  504.     }
  505.     return v;
  506. }
  507.  
  508. int
  509. digit(int i)
  510. {
  511.     if ('0'<=i && i<='9')
  512.         i -= '0';
  513.     else if ('a'<=i && i<='f')
  514.         i -= 'a'-10;
  515.     else if ('A'<=i && i<='F')
  516.         i -= 'A'-10;
  517.     else
  518.         i = -1;
  519.     return i;
  520. }
  521.